package cn.gs.algorithm;

// @author gs
import cn.gs.util.set.ArrayUtil;

public class NumberSplitUtil {

    public static double[] oneNullForZero(double[] rates) {
        if (1 == rates.length) {
            return new double[]{1};
        }
        double sum = 0;
        double[] rr = new double[rates.length];
        for (int i = 0; i < rates.length; ++i) {
            sum += rates[i];
        }
        if (0 == sum) {
            return null;
        }
        for (int i = 0; i < rates.length; ++i) {
            rr[i] = rates[i] / sum;
        }
        return rr;
    }

    public static double[] one(double[] rates) {
        if (1 == rates.length) {
            return new double[]{1};
        }
        double sum = 0;
        double[] rr = new double[rates.length];
        for (int i = 0; i < rates.length; ++i) {
            sum += rates[i];
        }
        for (int i = 0; i < rates.length; ++i) {
            rr[i] = (0 == sum ? 1 : rates[i] / sum);
        }
        return rr;
    }

    public static long[] split(long value, long... rates) {
        return split(false, value, ArrayUtil.longs2doubles(rates));
    }

    public static long[] split(long value, int... rates) {
        return split(false, value, ArrayUtil.ints2doubles(rates));
    }
    //DEMO

    public static long[] split(long value, double... rates) {
        return split(false, value, rates);
    }

    public static long[] split(boolean nullForZero, long value, double... rates) {
        long[] ret = new long[rates.length];
        double[] rr = nullForZero ? oneNullForZero(rates) : one(rates);
        if (null == rr) {
            return null;
        }
        if (ret.length > 0) {
            for (int i = 1; i < rates.length; ++i) {
                ret[i] = (long) (value * rr[i] + 0.5);
                value -= ret[i];
            }
            ret[0] = value;
        }
        return ret;
    }
}
